package com.zf.captcha.hutool;

import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.LineCaptcha;
import cn.hutool.captcha.generator.MathGenerator;
import cn.hutool.core.math.Calculator;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 测试
 */
@Slf4j
@RestController
@RequestMapping("/test/hutoolCaptcha")
public class TestHutoolCaptchaController {
    // 存储验证码，建议使用redis，因为redis可以设置过期时间，这里只是测试
    private static final ConcurrentHashMap<String, String> CODE_CACHE = new ConcurrentHashMap<>();


    /**
     * 使用生成器自定义生成的验证码格式：
     * 创建 四则运算 图形验证码
     */
    @GetMapping("/mathCode")
    public Map<String, String> createMathCode() throws IOException {
        // 创建数学生成器，设置生成的 四则运算式表达式 中参与计算的数字最大可以有几位，默认两位
        MathGenerator generator = new MathGenerator(2);
        // 使用线条干扰验证码，也可以使用其他类型的验证码，字符个数参数 是默认生成器生成的验证码长度，如果设置了新的生成器则以新生成器为准
        LineCaptcha lineCaptcha = CaptchaUtil.createLineCaptcha(200, 100, 0, 150);
        // 设置生成器，会导致原本的 字符个数参数 无效
        lineCaptcha.setGenerator(generator);

        // 获取验证码字符串，会生成一个四则运算表达式
        String code = lineCaptcha.getCode();
        // 计算表达式得到结果
        String res = String.valueOf((int) Calculator.conversion(code));

        // 暂存验证码, 生成一个唯一标识
        String captchaKey = UUID.randomUUID().toString();
        CODE_CACHE.put(captchaKey, res);

        // 1、把图形验证码写到输出流或者文件中
        // ServletOutputStream outputStream = response.getOutputStream();
        // lineCaptcha.write(outputStream);

        // 2、封装为json，将唯一标识和验证码图片返回给前端
        // 将图片转换为可以被 <img.src/> 属性使用的Base64数据
        String imageBase64 = lineCaptcha.getImageBase64Data();
        HashMap<String, String> result = new HashMap<>();
        result.put("captchaKey", captchaKey);
        result.put("image", imageBase64);
        return result;
    }

    /**
     * 校验验证码是否正确
     */
    @GetMapping("/verifyCode")
    public Map<String, String> verifyCode(@RequestParam("captchaKey") String captchaKey,
                                          @RequestParam("captchaResult") String captchaResult) {
        log.info("验证数据：captchaKey={}, captchaResult={}", captchaKey, captchaResult);

        // 获取缓存
        String cachedCaptchaResult = CODE_CACHE.get(captchaKey);
        // 获取后移除验证码，不管是否正确都移除，下一次使用新的验证码
        CODE_CACHE.remove(captchaKey);

        HashMap<String, String> result = new HashMap<>();
        // 前端传递了值 并且 和缓存一致，则成功
        if (StringUtils.hasText(captchaResult) && Objects.equals(cachedCaptchaResult, captchaResult)) {
            result.put("code", "200");
        } else {
            // 否则错误
            result.put("code", "0");
        }
        return result;
    }

}
